import ast

from sqlalchemy import Column, Integer, String, ForeignKey, orm
from sqlalchemy.orm import relationship, backref

from app.models.base import db
from app.models.base import Base
from app.models.case_group import CaseGroupModel


class CaseModel(Base):
    """
    用单例
    """
    __tablename__ = 'case'
    id = Column(Integer, primary_key=True)
    name = Column(String(80), nullable=False, comment='用例名称')
    method = Column(String(80), nullable=False)
    url = Column(String(180), nullable=False, comment='请求地址')
    headers = Column(String(180), comment='请求头')
    body = Column(String(5000), comment='请求体')
    params = Column(String(1000), comment='请求参数')
    condition = Column(String(10000), comment='后置处理')
    update_user = Column(Integer)
    create_user = Column(Integer, ForeignKey('user.id'))
    execution_order = Column(Integer, nullable=False, comment='执行顺序')
    # 使用case_group表的id作为辅键
    group_id = Column(Integer, ForeignKey('case_group.id'))
    # 反向引用 CaseModel.cases 返回用例组所有的用例并按照执行顺序返回
    group = relationship('CaseGroupModel', backref=backref('cases'))

    @orm.reconstructor
    def __init__(self):
        super(CaseModel, self).__init__()
        self.fileds = ['id', 'name', 'method', 'url', 'headers', 'body', 'params', 'create_user', 'execution_order',
                       'group_id', 'condition', 'update_user']

    def keys(self):
        return self.fileds

    @staticmethod
    def add_case(case_data):
        with db.auto_commit():
            case = CaseModel()

            case.name = case_data['name']
            case.method = case_data['method']
            case.url = case_data['url']
            case.headers = case_data['headers']
            case.body = case_data['body']
            case.params = case_data['params']
            case.group_id = case_data['group_id']
            case.create_user = case_data['create_user']
            case.update_user = case_data['update_user']
            case.execution_order = case_data['execution_order']
            case.condition = case_data['condition']
            db.session.add(case)

    @staticmethod
    def update_case(case_data):
        try:
            with db.auto_commit():
                case = CaseModel().query.filter_by(id=case_data['id']).first_or_404()
                case.name = case_data['name']
                case.method = case_data['method']
                case.url = case_data['url']
                case.headers = case_data['headers']
                case.body = case_data['body']
                case.params = case_data['params']
                case.group_id = case_data['group_id']
                case.update_user = case_data['update_user']
                case.execution_order = case_data['execution_order']
                case.condition = case_data['condition']
                db.session.commit()
        except:
            CaseModel.add_case(case_data)

    @staticmethod
    def update_add_case(case_list):
        # 获取用例组的全部case
        c_list = CaseGroupModel().query.filter_by(id=case_list[0]['group_id']).first_or_404().cases
        old_list = []
        for case in case_list:
            case['headers'] = str(case['headers']).encode().decode('utf-8')
            case['params'] = str(case['params']).encode().decode('utf-8')

            if case['id']:
                CaseModel.update_case(case)
                for c in c_list:
                    if c.id == case['id']:
                        old_list.append(c)

            else:
                CaseModel.add_case(case)
        # 删除剩余的原始case
        with db.auto_commit():
            all_list = filter(lambda x: x.status != 0, c_list)
            for c in all_list:
                if c in old_list:
                    continue
                c.delete()
            db.session.commit()

    @staticmethod
    def get_case(group_id):
        data_list = []
        case_list = CaseGroupModel().query.filter_by(id=group_id).first_or_404().cases
        new_list = list(filter(lambda x: x.status != 0, case_list))
        for c in new_list:
            # 获取update user信息
            try:
                update_user_model = CaseModel().query.filter_by(id=c.update_user).first_or_404()
                nickname = update_user_model.nickname
            except:
                nickname = '用户已注销'
            c.update_user_info = {"nickname": nickname, 'avatar_src': ''}
            c.add_keys('update_user_info')
            data_list.append(c)
        return sorted(data_list, key=lambda g: g.execution_order)
